#include <iostream>
#include "rs_table.h"
#include "rs_dict.h"
#include "rs_convert.h"
#include "rs_mwiki.h"
#include "rs_log.h"
#include "rs_respell.h"
#include "rs_http_proxy.h"
using namespace std;


static rs_string& t (const char* arg)
{
    return rs_command::get_appl().t (rs_stringed(arg));
} // textual argument


static unsigned&  n (const char* arg) {
    return rs_command::get_appl().n (rs_stringed(arg));
} // numeric argument

static bool  b (const char* arg) {
    return rs_command::get_appl().n (rs_stringed(arg)) != 0;
} // logical argument

//-----------------------------------------------------------------------------
rs_string cmd_group_conversion=L"Orthography-conversion";
//-----------------------------------------------------------------------------
bool cmd_conv() {
    converter& cnv = rs_command::get_appl().m_conversions.get_converter 
        (t("iog"), t("oog"), t("affixcg"), t("properlc"), b("show-unknown"));
    return cnv.convert_file (t("ifile"), t("ofile"), t("format"), b("keep"));
}
rs_command conv_rsc(cmd_conv, cmd_group_conversion,
    "conv\r"
    "iog:to:abbreviation of source (input) orthography\n"
    "oog:sp:abbreviation of target (output) orthography\n"
    "ifile:text.txt:file name to convert, wildcards (*?) are not allowed\n"
    "ofile::name of the created file\n"
    "show-unknown/b:+:if true, words that are unknown, are shown with asterick(*) or plus(+)\n"
    "keep/b:-:if true, converted .ispell file keep words from TO that were respelled\n"
    "affixcg:en_affix_cg.rst:name of file with common and grop affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "format::convert file as if it had this extension\n"
    "\r"
    "Converts a file from one orthography (OG) to another\r"
    "Converts in_file.ext, known file extensions are\n"
    "  txt: text files\n"
    "  htm/html: web hypertext files\n"
    "  ispell: spelling dictionary as used in program Abiword\n"
    "  strings: localization files as used in program Abiword\n"
    "  po: localization file\n"
    "Format is autodetected by file extension.\n"
    "If autodetection doesn't work, it can be specified with argument /format.");
//-----------------------------------------------------------------------------
bool cmd_cdir() {
    converter& cnv = rs_command::get_appl().m_conversions.get_converter 
        (t("iog"), t("oog"), t("affixcg"), t("properlc"), b("show-unknown"));
    return cnv.convert_directory (t("idir"), t("odir"), b("keep"));
}
rs_command cdir_rsc(cmd_cdir, cmd_group_conversion,
    "cdir\r"
    "iog:to:abbreviation of source (input) orthography\n"
    "oog:sp:abbreviation of target (output) orthography\n"
    "idir:.\n"
    "odir:\n"
    "show-unknown/b:-:if true, words that are unknown, are shown with asterick(*) or plus(+)\n"
    "keep/b:-:if true, converted .ispell file keep words from TO that were respelled\n"
    "affixcg:en_affix_cg.rst:name of file with common and grop affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "\r"
    "Converts all files in a directory\r"
    "Files with known extensions are converted, other files are copied.\n"
    "Name of output directory is automatically determined.");
//-----------------------------------------------------------------------------
bool cmd_http_cmd() {
    rs_log_set_time_stamps (true);
    converter& cnv = rs_command::get_appl().m_conversions.get_converter 
        (L"to", t("bog"), t("affixcg"), t("properlc"), false);
    rs_http_proxy(n("port"), cnv);
    return true;
}
rs_command http_cmd_rsc(cmd_http_cmd, cmd_group_conversion,
    "http_cmd\r"
    "port/n:8000:TCP port to use\n"
    "bog:sp:abbreviation of orthography seen in internet browser\n"
    "affixcg:en_affix_cg.rst:name of file with common and grop affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "\r"
    "Converts http:// text, running as command\r"
    "Runs indefinetly until it is interrupted by ctrl+c.\n"
    "Serves as http proxy for internet browsers");
//-----------------------------------------------------------------------------
bool cmd_http_service() {
    rs_log_set_time_stamps (true);
    converter& cnv = rs_command::get_appl().m_conversions.get_converter 
        (L"to", t("bog"), t("affixcg"), t("properlc"), false);
    rs_http_proxy(n("port"), cnv);
    return true;
}
rs_command http_service_rsc(cmd_http_service, cmd_group_conversion,
    "http_service\r"
    "port/n:8000:TCP port to use\n"
    "bog:sp:abbreviation of orthography seen in internet browser\n"
    "affixcg:en_affix_cg.rst:name of file with common and grop affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "\r"
    "Converts http:// text, running as Windows service\r"
    "Runs indefinetly until it is interrupted by ctrl+c.\n"
    "Serves as http proxy for internet browsers");
//-----------------------------------------------------------------------------
bool cmd_dcreate() {
    dcreate cd;
    bool result = cd.create_top ( t("bpd"), t("options"), t("cdir"), t("ro"),
        t("conv"), t("dict"), b("keep"), t("affixcg"), t("properlc"), t("sort"),
        b("common"), t("rflag"), t("kaffixes"), n("minfreq"), t("debugw"));
    rs_log_console (L"Cleaning up, then exiting.");
    return result;
};
rs_command dcreate_rsc(cmd_dcreate, cmd_group_conversion,
    "dcreate\r"
    "bpd:u1:base name of pronouncing dictionary, see command 'pdcombine'\n"
    "options:.:specifies which ROs dictionaries to create\n"
    "cdir::if non-empty, directory to convert from TO after RO dictionary is created\n"
    "ro::base name of respelled orthography; default is /bpd\n"
    "conv::name of input file with conversion rules; default is /bpd+_pron_conv.rst\n"
    "dict::name of output pronouncing dictionary file; default is /bpd+_pron_dict.rst\n"
    "keep/b:-:same as in commands 'conv' and 'cdir'\n"
    "affixcg:en_affix_cg.rst:name of file with common and group affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "sort:+or_to_us:'+' or '-' followed by column name\n"
    "common/b:+:if true, only non-proper words with positive frequencies are included\n"
    "rflag::required flag for inclusion to RO dictionary; e.g. puk, pus\n"
    "kaffixes::comma-separated list of affixes to be kept unchanged\n"
    "minfreq/n:0:minimal necessary value in column FREQX\n"
    "debugw::debugging word\n"
    "\r"
    "Creates RO dictionary(s) and optionally converts directory\r"
    "Creates a RO dictionary based on /dict dictionary\n"
    "and rules in /conv table\n"
    "If the first character of /options is '.', a plain RO dictionary is created\n"
    "named /bpd+_dict.rst. The rest of /options works as follows:\n"
    "If rest is plus '+', RO dictionaries for all options (one at a time)\n"
    "are created.\n"
    "If rest is in format 'active*combining', many dictionaries are created.\n"
    "Options listed as 'active' are always activated.\n"
    "All the combinations of 'combining' options are created.\n"
    "If /kaffixes is '*', all affixes are kept unchanged.\n"
    "An example for /kaffixes is '-s,-ing,re-'"
    );
//-----------------------------------------------------------------------------
bool cmd_dstat() {
    dcreate cd;
    return cd.show_statistics ( t("bpd"), t("conv"), t("dict"),
        t("sort"), t("coptions"), b("export"));
}
rs_command dstat_rsc(cmd_dstat, cmd_group_conversion,
    "dstat\r"
    "bpd:u1:base name of pronouncing dictionary, see command 'pdcombine'\n"
    "conv::name of input file with conversion rules; default is /bpd+_pron_conv.rst\n"
    "dict::name of output pronouncing dictionary file; default is /bpd+_pron_dict.rst\n"
    "sort:-freq:'+' or '-' followed by column name\n"
    "export/b:-:if true, tab-separated export file is generated\n"
    "coptions::comma-separated list of conversion options to process\n"
    "\r"
    "Calculates statistics about pronouncing dictionary\r"
    "Parses file /bpd+_pron_conv.rst and outputs all the listed statistics\n"
    "on the dictionary /bpd+_pron_dict.rst\n"
    "It also exports an output table for each conversion option,\n"
    "name is based on /bpd.\n"
    "If no /coptions are specified, all options are processed.\n"
    "To see the relative frequencies, in /coptions specify first the option 'all'.");
//-----------------------------------------------------------------------------
bool cmd_pdcombine() {
    rs_string out_dict = t("bpd")+L"_pron_dict";
    import imp (out_dict, L"PR", L"pronouncing dictionary", L"en-x-respell-pron");
    return imp.pron_dict_combine (t("us"), t("uk"), t("freq"),
        t("bpd")+L"_pron_conv.rst", t("case"), t("affixcg"),
        t("start"), n("limit"), b("pus"), b("puk"));
}
rs_command pdcombine_rsc(cmd_pdcombine, cmd_group_conversion,
    "pdcombine\r"
    "bpd:u1:base name of pronouncing dictionary\n"
    "us:us_dict.rst:name of pronouncing table for US English\n"
    "uk:uk_dict.rst:name of pronouncing table for UK English\n"
    "freq:freq.rst:name of frequency table\n"
    "case:case.rst:name of table with uppercase and lowercase words\n"
    "og:to.rst:name of table grammar (affix) structure\n"
    "affixcg:en_affix_cg.rst:name of file with common and grop affix data\n"
    "properlc:proper_lc.rst:name of file with proper nouns; in the table, they're written in lower case\n"
    "start::skip words before this starting word or prefix\n"
    "limit/n:0:if >0, take at most so many rows from each pronouncing table\n"
    "pus/b:+:flag to process US pronouncing table\n"
    "puk/b:+:flag to process UK pronouncing table\n"
    "\r"
    "Combines several tables into pronouncing dictionary\r"
    "  - raw dictionary table(s) /us and /uk, created with timport command\n"
    "    one for US English, from cmudict.0.6d\n"
    "    one for UK english, from beep-1.0\n"
    "  - frequency table /freq, self made\n"
    "  - /case table, from moby's case.txt\n"
    "  - pronouncing conversion table named /bpd+_pron_conv.rst, self made\n"
    "File names uk_dict.rst and us_dict.rst are actually fixed\n"
    "as the same tables are used also for grammars."
    );
//-----------------------------------------------------------------------------
bool cmd_import50() {
    import imp (t("out")+L"_dict", t("out"), t("name"),
        L"en-x-respelled-"+t("out"));
    return imp.convert_d50 (t("in"), t("freq"));
}
rs_command import50_rsc(cmd_import50, cmd_group_conversion,
    "import50\r"
    "in:diambg:input file name with pairs of 25-characters per word\n"
    "out:SD:abbreviation of orthography, also base name of dictionary\n"
    "name:respelled orthography\n"
    "tag:en-x-respelled\n"
    "freq:freq.rst\n"
    "\r"
    "Converts dictionary as in btrspl.zip into internal format\r"
    "Two dictionary files are provided, diambg (SD) and dicsbg (CS)");
//-----------------------------------------------------------------------------
bool cmd_usuk() {
    import imp (t("out")+L"_dict", t("out"), t("name"),
        L"en-x-respelled-"+t("out"));
    return imp.convert_d50 (t("in"), t("freq"));
}
rs_command usuk_rsc(cmd_import50, cmd_group_conversion,
    "usuk\r"
    "in:u1_pron_dict:input dictionary\n"
    "out:u1_pron_dict2:output dictionary\n"
    "\r"
    "Updates the US and UK spelling in dictionary\r"
    "Updates the columns OR_TO_US and OR_TO_UK");
//-----------------------------------------------------------------------------
rs_string cmd_group_table=L"Respelling table (.rst) modification";
//-----------------------------------------------------------------------------
bool cmd_timport() {
    rs_log_console (L"Importing text file " + t("in") + L" to table " + t("out"));
    rs_table rst;
    if (!rst.add_columns (t("columns")))
        return false;
    rst.import_table (t("in"), t("skip"), false);
    if (!rst.is_valid())
        return false;
    return rst.write (t("out"));
}
rs_command timport_rsc (cmd_timport, cmd_group_table,
    "timport\r"
    "in:table.txt:plus-separated list of input tables\n"
    "out:out.rst:file name of the output table\n"
    "columns:t0,T,20;t1,T,10:semicolon-delimited list of columns\n"
    "skip::if line starts on this string, it is skipped\n"
    "\r"
    "Imports text file\r"
    "Every line in input file is expected to have fields as specified in /columns.\n"
    "The first field has no spaces or tabulators inside.\n"
    "The rest of line is the second field.\n"
    "Spaces around fields are truncated, spaces within the second field\n"
    "are converted to underlines (_).\n"
    "Every column is specified in a way similar as in .rst file: \n"
    "three fields, separated by commas: name, type, output width\n"
    "There are three possibsle types:\n"
    " T: textual, no fast searching (not hashed) for this column\n"
    " T#: textual, fast searching (hashed) for this column\n"
    " N: numeric, 32-bit unsigned integers"
    );
//-----------------------------------------------------------------------------
bool cmd_tmodify() {
    rs_log_console (L"Modifying table(s) " + t("in") + L" to table " + t("out"));
    rs_table rst (t("in"), false);
    if (!rst.is_valid())
        return false;
    rst.set_numbered (b("numbered"));
    if (!rst.add_columns (t("add")))
        return false;
    if (!rst.change_case (t("lowercase"), false))
        return false;
    if (!rst.change_case (t("uppercase"), true))
        return false;
    bool result;
    if (b("export"))
        result = rst.export_table (t("out"));
    else
        result = rst.write (t("out"));
    return result;
}
rs_command tmodify_rsc (cmd_tmodify, cmd_group_table,
    "tmodify\r"
    "in:sd.rst:plus-separated list of input tables\n"
    "out:out.rst:file name of the output table\n"
    "numbered/b:+:if true and /export is false, output table is numbered\n"
    "export/b:-:if true, tab-separated export file is generated\n"
    "add::semicolon-separated list of columns to add\n"
    "lowercase::semicolon-separated list of column names to be converted to lowercase\n"
    "uppercase::semicolon-separated list of column names to be converted to uppercase\n"
    "\r"
    "Uniformly formats table /in or concatenates several tables together\r"
    "Reads the input table(s) and writes it to the output file\n"
    "Adds wanted columns and converts columns to lower-case or upper-case.\n"
    "Argument /in is plus-separated list of table file names, e.g. 'cs.rst'\n"
    "or 'sd_affix.rst+sd.rst'"
    "Every column for /add is specified in a way similar as in .rst file: \n"
    "three fields, separated by commas: name, type, output width\n"
    "There are three possibsle types:\n"
    " T: textual, no fast searching (not hashed) for this column\n"
    " T#: textual, fast searching (hashed) for this column\n"
    " N: numeric, 32-bit unsigned integers"
    );
//-----------------------------------------------------------------------------
bool cmd_tselect() {
    rs_log_console (L"Selecting data from table " + t("in")
        + L" to table " + t("out")
        + L", conditions " + t("conditions")
        + L", columns " + t("columns")
        + L", sorting " + t("sort")
        + L", max rows limit " + rs_stringed(n("max")));
    rs_table rst (t("in"), false);
    if (!rst.is_valid())
        return false;
    rst.write (t("out"), t("columns"), t("conditions"), t("sort"),
        rs_rix(n("max")));
    return true;
}
rs_command tselect_rsc (cmd_tselect, cmd_group_table,
    "tselect\r"
    "in:sd.rst:plus-separated list of input tables\n"
    "out:out.rst:file name of the output table\n"
    "conditions:\n"
    "columns:*:comma-separated list of column names\n"
    "sort::'+' or '-' followed by column name\n"
    "max/n:999999:maximal number of data rows in output table\n"
    "\r"
    "Copies selected columns and rows from table(s) /in to /out\r"
    "argument conditions is comma-separated list of\n"
    "  numeric-columns comparisons (e.g. freq>=10) or\n"
    "  string-columns regex matches (e.g. or_to:.*tion$)");
//-----------------------------------------------------------------------------
bool cmd_tjoin() {
    rs_log_console (L"Joining data from table " + t("in")
        + L" (to table " + t("out")
        + L"), with table " + t("join")
        + L", link " + t("link")
        + L", columns " + t("columns"));
    rs_table rst_base (t("in"), false);
    rs_table rst_join (t("join"));
    if (!rst_base.is_valid() || !rst_join.is_valid())
        return false;
    rst_base.join_table (rst_join, t("link"), t("columns"));
    rst_base.write (t("out"), L"", L"", t("sort"), rs_rix(n("max")));
    return true;
}
rs_command tjoin_rsc (cmd_tjoin, cmd_group_table,
    "tjoin\r"
    "in:cmu.rst:input table\n"
    "out:cmu1.rst:output table\n"
    "join:mw3_lc.rst\n"
    "link:or_to==or_to:column name from /in, operator '==' and column name from /join\n"
    "columns:fr_lc:comma-separated list of column names to join\n"
    "sort::'+' or '-' followed by column name\n"
    "max/n:999999:maximal number of data rows in output table\n"
    "\r"
    "Joins specified columns from table /join and produces table /out\r"
    "For every row in table /in, searches for corresponding row in table /join -\n"
    "correspondence is established with /link - and adds specified /columns\n"
    "Linking column from /join needs to be hashed"
    );
//-----------------------------------------------------------------------------
rs_string cmd_group_wiki=L"Wiki corpus processing";
//-----------------------------------------------------------------------------
bool cmd_wix() {
    mwiki mw (t("xml-fname"));
    return mw.create_store_index();
}
rs_command wix_rsc (cmd_wix, cmd_group_wiki,
    "wix\r"
    "xml-fname:mw1.xml:mediawiki .xml database dump\n"
    "\r"
    "Creates title index for mediawiki articles\r"
    "Two files are created, textual index (_ix.txt) and binary index (_ix.bin)");
//-----------------------------------------------------------------------------
bool cmd_wext() {
    rs_log_console (
        L"reserved space for " + rs_stringed(n("reserved")) + L" words"
        + L", context count: " + rs_stringed(n("count"))
        + L", context token size: " + rs_stringed (n("size")));
    mwiki mw (t("in"));
    mw.mw_ctx_count = n("count");
    mw.mw_ctx_size = n("size");
    if (!mw.read_binary_index (0, 10000000))
        return false;
    if (!mw.process_wikipedia (L".", 0, 10000000, n("reserved")))
        return false;
    if (!mw.write_freq())
        return false;
    return true;
}
rs_command wext_rsc (cmd_wext, cmd_group_wiki,
    "wext\r"
    "in:mw1.xml:mediawiki .xml database dump\n"
    "reserved/n:7000000:upward rounded estimate of number of different words\n"
    "count/n:5:so many contexts to remember\n"
    "size/n:30:size of context, in tokens\n"
    "\r"
    "Extracts and counts latinic words from indexed mediawiki .xml file\r"
    "It is expected that the command 'wix' has alreay created index\n"
    "Command 'wext' then extracts all the words into _freq.rst and _ctx.rst tables");
//-----------------------------------------------------------------------------
bool cmd_wget() {
    // extracts one or few or all articles from indexed wiki xml file
    // --wget mwiki.xml init_no count prefix
    mwiki mw (t("xml-fname"));
    if (!mw.read_binary_index  (n("init"), n("count")))
        return false;
    rs_log_console (L"writing articles " + t("prefix") + L"_" 
        + rs_stringed (n("init")) + L"*.txt"
        + L" to " + t("prefix") + L"_" + rs_stringed(n("init")+n("count")-1)
        + L"*.txt");
    if (!mw.process_wikipedia (t("prefix"), n("init"), n("count"), 0))
        return false;
    return true;
}
rs_command wget_rsc (cmd_wget, cmd_group_wiki,
    "wget\r"
    "xml-fname:mw1.xml:mediawiki .xml database dump\n"
    "init/n:0:initial article number\n"
    "count/n:1:number of articles to extract\n"
    "prefix:art:prefix for output article files\n"
    "\r"
    "Extracts one or few or all articles from indexed wiki xml file\r"
    "Note: numbers refer to articles, not to entries");
//-----------------------------------------------------------------------------
bool cmd_wclean() {
    rs_string in_fname (t("article"));
    rs_log_init (L"Cleaning mwiki markup from file " + in_fname);
    rs_istream ifs (in_fname);
    if (!ifs.good())
        return false;
    utf8_string text;
    rs_string wtext;
    ifs.read_file_bytes (text);
    rs_string out_fname (in_fname);
    replace_file_substring (out_fname, L".txt", L"_cln.txt");
    replace_file_substring (out_fname, L"_def.txt", L"_cln.txt");
    clean_all_wiki_markup (0, text, false);
    rs_log_console (L" to file " + out_fname);
    rs_ostream ofs (out_fname);
    if (!ofs.good())
        return false;
    utf8_to_wstring (text, wtext);
    if (!ofs.write (text.c_str(), (int) text.length()))
        return false;
    return true;
}
rs_command wclean_rsc (cmd_wclean, cmd_group_wiki,
    "wclean\r"
    "article:art1_def.txt:name of input files, extracted with command 'wget'\n"
    "\r"
    "Cleans mediawiki markup from input file to output file\r"
    "It creates a clean textual (_cln.txt) file");
//-----------------------------------------------------------------------------
rs_string cmd_group_testing=L"Testing (quality-assurance) support";
//-----------------------------------------------------------------------------
bool cmd_batch() {
    return rs_command::get_appl().run_batch (t("batch-fname"));
}
rs_command batch_rsc (cmd_batch, cmd_group_testing,
    "batch\r"
    "batch-fname:rs_test.txt:textual file with respell.exe commands\n"
    "\r"
    "Runs commands listed in file, similar to the .bat files\r"
    "Batch commands are suitable for testing that new versions don't break\n"
    "any features that already ran well in past versions.");
//-----------------------------------------------------------------------------
bool cmd_test_ref_dir() {
    rs_command::get_appl().m_test_ref_dir = t("dir");
    return true;
}
rs_command test_ref_dir_rsc (cmd_test_ref_dir, cmd_group_testing,
    "test-ref-dir\r"
    "dir:.\\:directory (folder) where reference files are stored\n"
    "\r"
    "Sets the directory that is used in 'test' command\r"
    "This string is prefixed to the base file name");
//-----------------------------------------------------------------------------
bool cmd_test() {
    rs_string fname1 (t("fname1"));
    rs_string fname2 (choose_str(
        t("fname2"),
        rs_command::get_appl().m_test_ref_dir+t("fname1")
        ));
    bool result = compare_text_files (fname1, fname2);
    rs_command::get_appl().m_test_cnt++;
    if (!result)
        rs_command::get_appl().m_failed_cnt++;
    return true;
}
rs_command test_rsc (cmd_test, cmd_group_testing,
    "test\r"
    "fname1:test.txt:first textual output file to be compared\n"
    "fname2::second textual output file to be compared\n"
    "\r"
    "Compares two textual files\r"
    "If any difference is found, outputs a string\n"
    "When the program exits, it also outputs a summary of passed and failed tests.\n"
    "If the second argument /fname2 is empty, it is taken to be\n"
    "directory set by 'test-ref-dir' command followed by /fname1.");
//-----------------------------------------------------------------------------
rs_string cmd_group_help=L"Help on program usage";
//-----------------------------------------------------------------------------
bool cmd_arguments() {
    cout <<
"Command names are case-insensitive, so e.g. either 'respell conv' or\n"
"'respell CONV' invokes the same command. Furthermore, any command\n"
"can be abbreviated to 3 or more characters.\n" 
"Most of commands require arguments. Every argument has a name, type and \n"
"default value. Argument names (when used) can be abbreviated to 3 or more\n"
"characters and are case-insensitive.\n" 
"There are 3 argument types: textual, numeric and logical.\n" 
"- Textual type can take any string. Current implementation accepts spaces\n"
"  only if the textual argument is quoted and entered as positional argument.\n" 
"- Numeric argument take any unsigned number, written in decimal notation.\n" 
"- Logical argument values (also known as switches or flags) are either true,\n" 
"  written as '+', or false, written as '-'.\n" 
"When specifying arguments, they can be entered in two possible forms.\n" 
"- As positional arguments, they are specified in the same order (position)\n"
"  as listed in help. Only argument value is specified.\n" 
"- As named arguments, they can be specified in any order.\n" 
"  Both argument name and value needs to be specified. Name is preceed\n"
"  by slash (/) and followed by colon (:).\n" 
"Example of positional and named arguments:\n" 
"    respell conv TO CS text-en.txt\n" 
"    respell conv /iog:TO /oog:CS /ifile:text-en.txt\n" 
"Both previous commands do the same.\n"
"Both forms can be mixed. If an argument is not specified,\n"
"it assumes default value.\n" 
"Additional short-cut is that logical values when specified as named arguments\n" 
"can omit colon and value. The assumed value is true (+).\n" 
        ;
    return true;
}
rs_command arguments_rsc (cmd_arguments, cmd_group_help,
    "arguments\r"
    "none::No arguments are necessary\n"
    "\r"
    "Displays help on command-line arguments\r"
    "",
    true);
//-----------------------------------------------------------------------------
bool cmd_all() {
    // dummy, only name is used for easier help processing
    return true;
}
rs_command all_rsc (cmd_all, cmd_group_help,
    "all\r"
    "none::No arguments are necessary\n"
    "\r"
    "\r"
    "",
    true);
//-----------------------------------------------------------------------------
bool cmd_help() {
    return rs_command::get_appl().cmd_line_help (t("command"));
}
rs_command help_rsc (cmd_help, cmd_group_help,
    "help\r"
    "command::name of the command to be described in detail\n"
    "\r"
    "Displays summary of commands or details of a single command\r"
    "Two special commands can be used for displaying help\n"
    "Command 'arguments' explains rules for arguments.\n"
    "Command 'all' prints all the help texts:");
//-----------------------------------------------------------------------------
bool cmd_copyright() {
    cout << 

"Copyright (c) 2008-2011 Joze Fabcic (Yozheh Fabchich)\n"
"\n"
"Permission is hereby granted, free of charge, to any person obtaining a copy\n"
"of this software and associated documentation files (the \"Software\"), to deal\n"
"in the Software without restriction, including without limitation the rights\n"
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n"
"copies of the Software, and to permit persons to whom the Software is\n"
"furnished to do so, subject to the following conditions:\n"
"\n"
"The above copyright notice and this permission notice shall be included in\n"
"all copies or substantial portions of the Software.\n"
"\n"
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n"
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n"
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n"
"THE SOFTWARE.\n";

    return true;
}
rs_command copyright_rsc (cmd_copyright, cmd_group_help,
    "copyright\r"
    "\r"
    "Displays copyright text\r"
    "");
//-----------------------------------------------------------------------------
